package electionalgorithm.control;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import electionalgorithm.entity.Process;

/**
 * This class is used to do the initialization.
 * 
 * @since Oct 17, 2011
 * @author <a href="mailto:zexpp5@gmail.com">Zexu.Lin</a>
 * @version $Id: Initiator.java 28 2011-10-28 09:58:58Z zexpp5@gmail.com $
 * 
 */
public class Initiator {
	private static Logger logger = Logger.getLogger(Initiator.class);

	private Initiator() {
	}

	/**
	 * 
	 * @description initialization.
	 * 
	 * @author <a href="mailto:zexpp5@gmail.com">Zexu.Lin</a>
	 * @update Oct 21, 2011 2:37:46 PM
	 */
	public static HashMap<String, Process> init() {
		HashMap<String, Process> processes = creatProcesses();
		constructStructure(processes);
		return processes;
	}
	
	public static HashMap<String, Process> initRandomly(int n) {
		HashMap<String, Process> processes = creatProcesses(n);
		constructStructure(processes,n);
		return processes;
	}
	
	private static HashMap<String, Process> creatProcesses(int n) {
		HashMap<String, Process> processes = new HashMap<String, Process>();
		for (char i = 65; i-65 < n; i++) {
			
			processes.put(i + "", new Process(i + "",(int)(Math.random()*10000)));
		}
		
		return processes;
	}

	private static void constructStructure(HashMap<String, Process> processes,
			int n) {
		
		char current = 65;
		for (int numNodeTotal = n, numNodeLeft = n; numNodeLeft > 0; numNodeLeft--, current++) {
			if (numNodeLeft == numNodeTotal) {
				continue;
			} else {
				char parent = (char) (65 + (int) (Math.random() * (numNodeTotal - numNodeLeft)));
				Process currentProcess = processes.get(current + "");
				Process parentProcess = processes.get(parent + "");
				logger.info("     " + parentProcess.getId()
						+ "    got a child     " + currentProcess.getId() + "");
				parentProcess.setNeigh(currentProcess);
				currentProcess.setNeigh(parentProcess);

			}
		}
		
	}



	/**
	 * 
	 * @return
	 * @description to generate the processes.
	 * 
	 * @author <a href="mailto:zexpp5@gmail.com">Zexu.Lin</a>
	 * @update Oct 21, 2011 2:37:03 PM
	 */
	private static HashMap<String, Process> creatProcesses() {
		HashMap<String, Process> processes = new HashMap<String, Process>();
		for (char i = 65; i < 74; i++) {
			processes.put(i + "", new Process(i + "",(int)Math.random()*10));
		}
		
		return processes;
	}

	/**
	 * 
	 * @param processes
	 * @description to construct the tree structure of the generated process by
	 *              adding neighbors to each other.
	 * 
	 * @author <a href="mailto:zexpp5@gmail.com">Zexu.Lin</a>
	 * @update Oct 21, 2011 2:34:36 PM
	 */
	private static void constructStructure(HashMap<String, Process> processes) {
		char current = 65;
		for (int numNodeTotal = 9, numNodeLeft = 9; numNodeLeft > 0; numNodeLeft--, current++) {
			if (numNodeLeft == numNodeTotal) {
				continue;
			} else {
				char parent = (char) (65 + (int) (Math.random() * (numNodeTotal - numNodeLeft)));
				Process currentProcess = processes.get(current + "");
				Process parentProcess = processes.get(parent + "");
				logger.info("     " + parentProcess.getId()
						+ "    got a child     " + currentProcess.getId() + "");
				parentProcess.setNeigh(currentProcess);
				currentProcess.setNeigh(parentProcess);

			}
		}
	}
}
